package com.xxx.controller;

import com.alibaba.fastjson.JSONObject;
import com.xxx.pojo.Account;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

/**
 * @version v1.0
 * @Description:
 * @Author zhanzhongxin
 * @Date 2021/8/19 15:34
 * @Copyright 博为峰
 */
@Controller
@Slf4j
public class AccountController {

//    private static final Logger logger = LogManager.getLogger(AccountController.class);

    @RequestMapping(value = "/queryAccountByName", method = RequestMethod.GET)
    public String queryAccountByName(String name, @RequestParam(value = "money", required = false) int balance) {
        System.out.println("name = " + name);
        System.out.println("balance = " + balance);
        log.debug("abc");
        return "test";
    }

    @RequestMapping(value = "/addAccount", method = RequestMethod.POST)
    public String addAccount(@Validated Account account, BindingResult bindingResult, Model model) {
//        System.out.println("account = " + account);
        if (bindingResult.hasErrors()) {
            final List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.stream().forEach(e -> System.out.println(e.getDefaultMessage()));
        }
        return "index";
    }

    @RequestMapping("/testDate")
    //org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2021-08-20'; nested exception is java.lang.IllegalArgumentException]
    public String testDate(Date date) {
        System.out.println("date = " + date);
        return "test";
    }

    @RequestMapping("/testReqRespSe")
    public void testReqRespSe(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
        request.getRequestDispatcher("/success.jsp").forward(request, response);
//        response.sendRedirect(request.getContextPath() + "/success.jsp");
        session.setAttribute("name", "zhangsan");
    }

    @RequestMapping("/testHeader")
    public String testHeader(@RequestHeader("User-Agent") String UserAgent) {
        System.out.println("UserAgent = " + UserAgent);
        return "success";
    }

    @RequestMapping("/testCookie")
    public String testCookie(@CookieValue("JSESSIONID") String jid) {
        System.out.println("JSESSIONID = " + jid);
        return "success";
    }

    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView() {
        final ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("ul", Arrays.asList("zhangsan", "lisi", "wangwu"));
        modelAndView.setViewName("user-list");
        return modelAndView;
    }

    @RequestMapping("/testModelMapAndModel")
    public String testModelMapAndModel(ModelMap map, Model model) {
        map.addAttribute("map", Arrays.asList("m-zhangsan", "m-lisi", "m-wangwu"));
        model.addAttribute("model", Arrays.asList("zhangsan", "lisi", "wangwu"));
        return "redirect:user-list";
    }

    @RequestMapping("/testJson")
    @ResponseBody
    public Account testJson(Account account) {
        System.out.println("account = " + account);
        account.setBalance(2000);
//        JSONObject.toJSONString(account);
//        return JSONObject.toJSONString(account);
        return account;
    }

    @RequestMapping("/testJsonString")
    @ResponseBody
    public Account testJsonString(@RequestBody Account account) {
        System.out.println("account = " + account);
        account.setBalance(2000);
//        JSONObject.toJSONString(account);
//        return JSONObject.toJSONString(account);
        return account;
    }

    @RequestMapping("/testRESTful/{name}/{balance}")
    public String testRESTful(@PathVariable("name") String name, @PathVariable("balance") int balance) {
        System.out.println("name = " + name);
        System.out.println("balance = " + balance);
        return "success";
    }

    @RequestMapping("/testException")
    public String testException() {
        String[] array = {"zhangsan", "lisi"};
        System.out.println(array[2]);
        return "success";
    }

    @ExceptionHandler(RuntimeException.class)
    public void handleRuntimeException(Exception e) {
        System.out.println("RuntimeException");
        System.out.println(e.getMessage());
    }

    @RequestMapping("/testUpload")
    public String testUpload(MultipartFile multipartFile) throws IOException {
        //上传文件名称
        String filename = multipartFile.getOriginalFilename();
        Path savePath = Paths.get("D:\\workspace\\upload");
        if (!Files.exists(savePath)) {
            Files.createDirectory(savePath);
        }
        //设置本地文件保存的名称
        final String saveFileName = UUID.randomUUID().toString() + "_" + filename;
        //按时间设置本地文件保存路径
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String date = dateTimeFormatter.format(LocalDateTime.now());
        final Path saveFilePath = Paths.get("D:\\workspace\\upload\\" + date);
        if (!Files.exists(saveFilePath)) {
            Files.createDirectory(saveFilePath);
        }
        //创建本地文件
        final Path path = Paths.get(saveFilePath + "\\" + saveFileName);
        //存储文件
        multipartFile.transferTo(path);
        return "success";
    }

    @RequestMapping("/testDownload")
    public ResponseEntity<byte[]> testDownload() throws IOException {
        String path = "D:\\workspace\\upload\\2021-08-23\\";
        String fileName = "9cc0e088-09d3-4c5b-aba5-f0466c52631e_maven仓库.png";
        final Path downPath = Paths.get(path + fileName);
        //设置响应头
        final HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(StandardCharsets.UTF_8), "iso-8859-1"));
        //设置以二进制流的方式传输文件数据
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(downPath.toFile()), headers, HttpStatus.OK);
    }

//    @ModelAttribute
//    public void testModelAttribute() {
//        System.out.println("ModelAttribute");
//    }

    @ModelAttribute("acc")
    public Account testModelAttribute(Model model) {
        System.out.println("ModelAttribute");
        final Account account = new Account("zhangsan", 1000);
        model.addAttribute("account", account);
        return account;
    }
}
